package eu.irreality.dai.ui.wrapper;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

import eu.irreality.dai.gameplay.events.GameEvent;
import eu.irreality.dai.gameplay.world.GameWorld;
import eu.irreality.dai.util.ConfigurationParametersManager;
import eu.irreality.dai.util.Observable;
import eu.irreality.dai.util.Observer;

/*
 Created 26/08/2007 23:16:58
 */

public class DisplayFrame extends JFrame implements Observer
{

    private final static String WINDOW_WIDTH = "DisplayFrame/WindowWidth";
    private final static String WINDOW_HEIGHT = "DisplayFrame/WindowHeight";

    private Display display;
    private JPanel mainPanel;

    private double ratio;

    public DisplayFrame(Display display)
    {
	this.display = display;
	this.setContentPane(getMainPanel());
	this.setTitle("Descensus Ad Inferos");
	this.addComponentListener(new ComponentAdapter()
	{
	    @Override
	    public void componentResized(ComponentEvent e)
	    {
		super.componentResized(e);
		adjustSize();
	    }
	});

	this.pack();
	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	ratio = (double) this.getWidth() / (double) this.getHeight();

	this.setVisible(true);
    }

    public JPanel getMainPanel()
    {
	if (mainPanel == null)
	{
	    mainPanel = new DisplayPanel(display);

	    String widthSt = ConfigurationParametersManager.get(WINDOW_WIDTH);
	    String heightSt = ConfigurationParametersManager.get(WINDOW_HEIGHT);

	    if (widthSt == null)
	    {
		System.err
			.println("A property specifying the width of the window is missing. "
				+ "Please include a property "
				+ WINDOW_WIDTH
				+ " in config/ConfigurationParameters.properties. "
				+ "Instead, default size will be used now."
				+ "Sorry for the inconvenience.");
		widthSt = "1380";
		heightSt = "720";
	    }

	    if (heightSt == null)
	    {
		System.err
			.println("A property specifying the width of the window is missing. "
				+ "Please include a property "
				+ WINDOW_HEIGHT
				+ " in config/ConfigurationParameters.properties. "
				+ "Instead, default size will be used now."
				+ "Sorry for the inconvenience.");
		widthSt = "1380";
		heightSt = "720";
	    }

	    int width = Integer.parseInt(widthSt);
	    int height = Integer.parseInt(heightSt);
	    mainPanel.setPreferredSize(new Dimension(width, height));
	    mainPanel.setSize(width, height);
	    display.setPixelSize(mainPanel.getHeight(), mainPanel.getWidth());
	}
	return mainPanel;
    }

    private void adjustSize()
    {
	// double width = getSize().width;
	// double height = getSize().height;
	double width = getMainPanel().getSize().width;
	double height = getMainPanel().getSize().height;

	double r = width / height;
	System.out.println("r: " + r + ", ratio: " + ratio);
	System.out.println("width: " + width + ", height: " + height);
	if (r < ratio)
	{
	    width = height * ratio;
	    // setSize((int) width, (int) height);
	    getMainPanel().setPreferredSize(
		    new Dimension((int) width, (int) height));
	    pack();
	} else if (r > ratio)
	{
	    height = width / ratio;
	    // setSize((int) width, (int) height);
	    getMainPanel().setPreferredSize(
		    new Dimension((int) width, (int) height));
	    pack();
	}

    }

    public void reactToEvent(GameWorld gw, GameEvent theEvent)
    {
	if (theEvent.getType() == GameEvent.OPEN_DOOR)
	{
	    if (theEvent.getSubject() == gw.getPlayerCharacter())
	    {
		display.appendText(" You open the door.", Color.WHITE);
	    } else
	    {
		display.appendText(" A door opens somewhere.", Color.WHITE);
	    }
	} else if (theEvent.getType() == GameEvent.CLOSE_DOOR)
	{
	    if (theEvent.getSubject() == gw.getPlayerCharacter())
	    {
		display.appendText(" You close the door.", Color.WHITE);
	    } else
	    {
		display.appendText(" A door closes somewhere.", Color.WHITE);
	    }
	} else if (theEvent.getType() == GameEvent.TRY_TO_MOVE)
	{
	    if (theEvent.getSubject() == gw.getPlayerCharacter())
	    {
		display.appendText(" Impassable.", Color.RED.brighter()
			.brighter().brighter());
	    }
	} else if (theEvent.getType() == GameEvent.MOVE)
	{
	    if (theEvent.getSubject() == gw.getPlayerCharacter())
	    {
		display.setData("r", ""
			+ theEvent.getSubject().getPosition().getRow(),
			Color.blue.brighter());
		display.setData("c", ""
			+ theEvent.getSubject().getPosition().getCol(),
			Color.blue.brighter());
	    }
	} else if (theEvent.getType() == GameEvent.WHAT_DOOR)
	{
	    if (theEvent.getSubject() == gw.getPlayerCharacter())
	    {
		display.appendText(" What door?", Color.RED.brighter()
			.brighter().brighter());
	    }
	}
    }

    @Override
    public void update(Observable o, Object arg)
    {
	if (o instanceof GameWorld)
	{
	    GameWorld gw = (GameWorld) o;
	    if ("active_level_changed".equals(arg))
	    {
		display.setLevel(gw.getActiveLevel());
	    }
	    if (arg instanceof String[])
	    {
		if ("message".equals(((String[]) arg)[0]))
		{
		    display.appendText(((String[]) arg)[1], Color.WHITE);
		}
	    }
	    if (arg instanceof GameEvent)
	    {
		reactToEvent(gw, (GameEvent) arg);

	    }
	    getMainPanel().repaint();
	}
    }

    /* Test code. Uncomment for testing. */
    // public static void main(String[] args)
    // {
    // Display disp = new SimulatedAsciiDisplay();
    // disp.setSize(25, 80);
    //
    // disp.clear();
    //
    // for (int r = 0; r < 25; r++)
    // {
    // for (int c = 0; c < 80; c++)
    // {
    // if ((r + c) % 2 == 0)
    // disp.addContent(r, c, new DisplayableCharacter('#',
    // Color.RED));
    // else
    // disp.addContent(r, c, new DisplayableCharacter('#',
    // Color.GREEN));
    // }
    // }
    //
    // new DisplayFrame(disp);
    // }
}
